package com.cn.ycy.entity.result;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

import java.io.Serializable;

/**
 * 统一API响应结果封装
 *
@author qiss
 */
@Getter
@Setter
@ToString
@ApiModel(description = "返回信息")
@NoArgsConstructor(access = AccessLevel.PRIVATE)

public class R<T> implements Serializable {

    private static final long serialVersionUID = 1L;
    private static int SUCCESS_CODE = ResultCode.SUCCESS.getCode();
    private static int FAILURE_CODE = ResultCode.FAILURE.getCode();

    @ApiModelProperty(value = "状态码", required = true)
    private int resultCode;
    @ApiModelProperty(value = "承载数据")
    private T data;
    @ApiModelProperty(value = "返回消息", required = true)
    private String resultMessage;


    private R(int code, String message) {
        this.resultCode = code;
        this.resultMessage = message;
    }

    private R(int code, T data, String message) {
        this.resultCode = code;
        this.resultMessage = message;
        this.data = data;
	}


	private R(ResultCode resultCode) {
		this(resultCode.getCode(), resultCode.getMessage());
	}

	private R(ResultCode resultCode, String msg) {
		this(resultCode.getCode(), msg);
	}

	private R(ResultCode resultCode, T data) {
		this(resultCode, data, resultCode.getMessage());
	}

	private R(ResultCode resultCode, T data, String msg) {
		this(resultCode.getCode(), data, msg);
	}


    /**
     * 返回码,返回msg
     *
     * @return
     */
    public static <T> R<T> r(int resultCode, String msg) {
        return new R<>(resultCode, msg);
    }

    /**
     * 自定义分页返回
     *
     * @return
     */
    public static <T> R<T> r(int resultCode, T data, String msg) {
        return new R<>(resultCode, data, msg);
    }


    /**
	 * 返回R
	 *
	 * @param code 状态码
	 * @param data 数据
	 * @param msg  消息
	 * @param <T>  T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(int code, T data, String msg) {
		return new R<>(code, data, data == null ? RConstant.DEFAULT_NULL_MESSAGE : msg);
	}

	/**
	 * 返回R
	 *
	 * @param data 数据
	 * @param msg  消息
	 * @param <T>  T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(T data, String msg) {
		return success(SUCCESS_CODE, data, msg);
	}


	/**
	 * 返回R
	 *
	 * @param data 数据
	 * @param resultCode  rcode
	 * @param <T>  T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(T data, ResultCode resultCode) {
		return success(resultCode.getCode(), data, resultCode.getMessage());
	}

	/**
	 * 返回R
	 *
	 * @param data 数据
	 * @param <T>  T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(T data) {
		return success(data, RConstant.DEFAULT_SUCCESS_MESSAGE);
	}
	
	public static <T> R<T> success() {
		return success(RConstant.DEFAULT_SUCCESS_MESSAGE);
	}


	/**
	 * 如果是string则stirng也是位于data的值
	 * @param data
	 * @param <T>
	 * @return
	 */
	public static <T> R<T> successWithData(T data) {
		return success(SUCCESS_CODE, data, RConstant.DEFAULT_SUCCESS_MESSAGE);
	}

	/**
	 * 返回R
	 *
	 * @param msg 消息
	 * @param <T> T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(String msg) {
		return new R<>(SUCCESS_CODE, msg);
	}

	/**
	 * 返回R
	 *
	 * @param resultCode 业务代码
	 * @param <T>        T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(ResultCode resultCode) {
		return new R<>(resultCode);
	}

	/**
	 * 返回R
	 *
	 * @param resultCode 业务代码
	 * @param msg        消息
	 * @param <T>        T 泛型标记
	 * @return R
	 */
	public static <T> R<T> success(ResultCode resultCode, String msg) {
		return new R<>(resultCode, msg);
	}

	/**
	 * 返回R
	 *
	 * @param msg 消息
	 * @param <T> T 泛型标记
	 * @return R
	 */
	public static <T> R<T> failure(String msg) {
		return new R<>(FAILURE_CODE, msg);
	}
	
	public static <T> R<T> failure() {
		return new R<>(FAILURE_CODE, RConstant.DEFAULT_FAILURE_MESSAGE);
	}


	/**
	 * 返回R
	 *
	 * @param code 状态码
	 * @param msg  消息
	 * @param <T>  T 泛型标记
	 * @return R
	 */
	public static <T> R<T> failure(int code, String msg) {
		return new R<>(code, msg);
	}

	/**
	 * 返回R
	 *
	 * @param resultCode 业务代码
	 * @param <T>        T 泛型标记
	 * @return R
	 */
	public static <T> R<T> failure(ResultCode resultCode) {
		return new R<>(resultCode);
	}

	/**
	 * 返回R
	 *
	 * @param resultCode 业务代码
	 * @param msg        消息
	 * @param <T>        T 泛型标记
	 * @return R
	 */
	public static <T> R<T> failure(ResultCode resultCode, String msg) {
		return new R<>(resultCode, msg);
	}
	
	/**
	 * 空
	 * @return
	 */
	public static <T> R<T> none() {
		return new R<>();
    }

    public int getResultCode() {
        return resultCode;
    }

    public String getResultMessage() {
        return resultMessage;
	}

    /**
     * 获取当前存储对象
     *
     * @return
     */
    public T data() {
        return data;
    }

}
